/**
 * Created by meiguizhinian on 2018/6/26
 * Copyright © 2018 lixiaolong. All rights reserved.
 */

ivy.CocosActionDataManager = {
	getInstance : function () {
		return this;
	},

	initWithFile : function (filename) {
		let is = new ivy.InputStream(filename);
		cc.assert(!is.empty(), "读取文件失败"+filename);
		let sourceActionTypeCount = is.readJInt16();
		for (let i = 0; i < sourceActionTypeCount; ++i) {
			let typeName = is.readStringUTF8();
			let elementCount = is.readJInt16();
			let sActionType = new ivy.SourceActionType(typeName);
			for (let j = 0; j < elementCount; ++j) {
				let elementType = is.readJInt16();
				sActionType.getElementTypeVec().push(elementType);
			}
			this._sourceActionMap.push(sActionType);
		}

		let controlActionCount = is.readJInt16();
		for (let i = 0; i < controlActionCount; ++i) {
			let  cad = new ivy.ControlActionData();
			cad.isUsePreInitData = is.readInt8() === 1;
			if (cad.isUsePreInitData) {
				let posX=is.readJInt32();
				let posY=is.readJInt32();
				let scaleX=is.readJInt32();
				let scaleY=is.readJInt32();
				let rotateX= is.readJInt16();
				let rotateY= is.readJInt16();
				let rotateZ= is.readJInt16();
				let color=is.readJUInt32();
				cad.preInitPosition = cc.p(posX, posY);
				cad.preInitScaleX = scaleX / 100.0;
				cad.preInitScaleY = scaleY / 100.0;
				cad.preInitRotate = cc.math.vec3(rotateX, rotateY, rotateZ);
				cad.preInitColor = ivy.Tools.getColor4BFromInt32(color);
			}
			if (is.readJInt16() === 1) {
				//说明有主节点数据存在
				cad.rootActionData.vaild = true;
				this._readActionData(is, cad.rootActionData);
			} else {
				cad.rootActionData.vaild = false;
			}
			this._controlActionDataVec.push(cad);
		}
		//临时数据清空
		this._actionDataIntFindMap.clear();
		this._actionDataStringFindMap.clear();
		this._actionDataFloatFindMap.clear();
		this._actionDataVec2FindMap.clear();
		this._actionDataVec3FindMap.clear();
	},

	runActionByNode : function(node, actionID, Tag=-1) {
		this.runActionByNodeBy(node, actionID, null, Tag);
	},
	runActionByNodeBy : function(node, actionID, func, Tag = -1) {
		if (!node) {
			return;
		}
		if (actionID < 0 || actionID >= this._controlActionDataVec.length) {
			return;
		}
		this.setInitDataTo(node, actionID);
		let action = this.getGameActionBy(actionID);
		if (func) {
			action = func(action);
		}
		if (Tag >= 0) {
			action.setTag(Tag);
		}
		if (action) {
			node.runAction(action);
		}
	},

	registActionCreaterFunc : function(i, func) {
		this._cocosActionCreaterMap[i] = func;
	},

	getIntDataByFindIndex : function(index) {
		return this._actionDataIntMap.get(index) || 0;
	},

	getStringDataByFindIndex : function(index) {
		return this._actionDataStringMap.get(index) || "";
	},

	getFloatDataByFindIndex : function(index) {
		return this._actionDataFloatMap.get(index) || 0.0;
	},

	getVec2DataByFindIndex : function(index) {
		return this._actionDataVec2Map.get(index) || cc.p();
	},

	getVec3DataByFindIndex : function(index) {
		return this._actionDataVec3Map.get(index) || cc.math.vec3(0,0,0);
	},

	getGameActionBy : function(indexOrID) {
		if (indexOrID instanceof ivy.IDBaseT) {
			indexOrID = indexOrID.getValue();
		}
		let index = indexOrID;
		if (index < 0 || index >= this._controlActionDataVec.length) {
			return null;
		}
		return this._createGameActionBy(this._controlActionDataVec[index].rootActionData);
	},

	setInitDataTo : function(node, index) {
		if (!node) {
			return false;
		}
		if (index < 0 || index >= this._controlActionDataVec.length) {
			return false;
		}
		let actionData = this._controlActionDataVec[index];
		if (actionData.isUsePreInitData) {
			let p1 = node.getPosition();
			node.setPosition(cc.pAdd(p1, actionData.preInitPosition));
			let preInitColor = actionData.preInitColor;
			node.setColor(cc.color(preInitColor.r, preInitColor.g, preInitColor.b));
			node.setOpacity(actionData.preInitColor.a);
			node.setScale(actionData.preInitScaleX, actionData.preInitScaleY);
			node.setRotation3D(actionData.preInitRotate);
			return true;
		} else {
			return false;
		}
	},
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	_cocosActionCreaterMap : {},
	_createGameActionBy : function(data) {
		let vecTemp = [];
		for (let i = 0; i < data.childActionData.length; ++i) {
			let createdAction = this._createGameActionBy(data.childActionData[i]);
			if(createdAction) {
				vecTemp.push(createdAction);
			}
		}
		let actionDataTypeIndex = data.sourceActionTypeIndex;
		if (this._cocosActionCreaterMap[actionDataTypeIndex]) {
			return this._cocosActionCreaterMap[actionDataTypeIndex](data, vecTemp);
		}
		return null;
	},
	_readActionData : function(is, data) {
		let actionTypeIndex = is.readJInt16();
		data.sourceActionTypeIndex = actionTypeIndex;
		if (actionTypeIndex >= 0) {
			cc.assert(actionTypeIndex>=0 && actionTypeIndex< this._sourceActionMap.length);
			let propertyCount = is.readJInt16();
			//data.propertyDataFindIndex.resize(propertyCount); =>
			data.propertyDataFindIndex = [];

			cc.assert(propertyCount===this._sourceActionMap[actionTypeIndex].size(), actionTypeIndex);
			let sourceAction = this._sourceActionMap[actionTypeIndex];
			for (let i = 0; i < propertyCount; ++i) {
				switch (sourceAction.get(i)) {
					case ivy.SourceActionType.BaseElementType.eString: {
						let v = is.readStringUTF8();
						if (this._actionDataStringFindMap.has(v)) {
							data.propertyDataFindIndex[i] = this._actionDataStringFindMap.get(v);
						} else {
							let len = this._actionDataStringMap.size();

							this._actionDataStringFindMap.set(v, len);
							data.propertyDataFindIndex[i] = len;
							this._actionDataStringMap.set(len, v);
						}
						break;
					}
					case ivy.SourceActionType.BaseElementType.eInt: {
						let v = is.readJInt32();
						if (this._actionDataIntFindMap.has(v)) {
							data.propertyDataFindIndex[i] = this._actionDataIntFindMap.get(v);
						} else {
							let len = this._actionDataIntMap.size();

							this._actionDataIntFindMap.set(v, len);
							data.propertyDataFindIndex[i] = len;
							this._actionDataIntMap.set(len, v);
						}
						break;
					}
					case ivy.SourceActionType.BaseElementType.eList: {
						let v=is.readJInt16();
						if (this._actionDataIntFindMap.has(v)) {
							data.propertyDataFindIndex[i] = this._actionDataIntFindMap.get(v);
						} else {
							let len = this._actionDataIntMap.size();

							this._actionDataIntFindMap.set(v, len);
							data.propertyDataFindIndex[i] = len;
							this._actionDataIntMap.set(len, v);
						}
						break;
					}
					case ivy.SourceActionType.BaseElementType.eFloat: {
						let v = is.readJInt32() / 100.0;
						if (this._actionDataFloatFindMap.has(v)) {
							data.propertyDataFindIndex[i] = this._actionDataFloatFindMap.get(v);
						} else {
							let len = this._actionDataFloatMap.size();

							this._actionDataFloatFindMap.set(v, len);
							data.propertyDataFindIndex[i] = len;
							this._actionDataFloatMap.set(len, v);
						}
						break;
					}
					case ivy.SourceActionType.BaseElementType.eVec2: {
						let v1 = is.readJInt32();
						let v2 = is.readJInt32();
						let vec = cc.p(v1,v2);
						if (this._actionDataVec2FindMap.has(vec)) {
							data.propertyDataFindIndex[i] = this._actionDataVec2FindMap.get(vec);
						} else {
							let len = this._actionDataVec2Map.size();

							this._actionDataVec2FindMap.set(vec, len);
							data.propertyDataFindIndex[i] = len;
							this._actionDataVec2Map.set(len, vec);
						}
						break;
					}
					case ivy.SourceActionType.BaseElementType.eVec2F: {
						let v1 = is.readJInt32() / 100.0;
						let v2 = is.readJInt32() / 100.0;
						let vec = new cc.p(v1, v2);
						if (this._actionDataVec2FindMap.has(vec)) {
							data.propertyDataFindIndex[i] = this._actionDataVec2FindMap.get(vec);
						} else {
							let len = this._actionDataVec2Map.size();

							this._actionDataVec2FindMap.set(vec, len);
							data.propertyDataFindIndex[i] = len;
							this._actionDataVec2Map.set(len, vec);
						}
						break;
					}
					case ivy.SourceActionType.BaseElementType.eVec3: {
						let v1 = is.readJInt32();
						let v2 = is.readJInt32();
						let v3 = is.readJInt32();
						let vec = cc.math.vec3(v1, v2, v3);
						if (this._actionDataVec3FindMap.has(vec)) {
							data.propertyDataFindIndex[i] = this._actionDataVec3FindMap.get(vec);
						} else {
							let len = this._actionDataVec3Map.size();

							this._actionDataVec3FindMap.set(vec, len);
							data.propertyDataFindIndex[i] = len;
							this._actionDataVec3Map.set(len, vec);
						}
						break;
					}
					default:
						break;
				}
			}

			let childCount = is.readJInt16();
			for (let i = 0; i < childCount; ++i) {
				let newActionData = new ivy.ActionData();
				data.childActionData.push(newActionData);
				this._readActionData(is, data.childActionData[data.childActionData.length-1]);
			}
		}
	},

	_sourceActionMap : [],//std::vector<SourceActionType>
	_controlActionDataVec : [],//std::vector<ControlActionData>
	//////////////////////////////////////////////////////////////////////////
	_actionDataIntMap : new LLDictionary(),//std::map<int32_t, int32_t>
	_actionDataStringMap : new LLDictionary(),//std::map<int32_t, std::string>
	_actionDataFloatMap : new LLDictionary(),//std::map<int32_t, float>
	_actionDataVec2Map : new LLDictionary(),//std::map<int32_t, cocos2d::Vec2>
	_actionDataVec3Map : new LLDictionary(),//std::map<int32_t, cocos2d::Vec3>
	//读取数据时临时使用的容器 读取完成后清空
	_actionDataIntFindMap : new LLDictionary(),//std::map<int32_t, int32_t>
	_actionDataStringFindMap : new LLDictionary(),//std::map<std::string, int32_t>
	_actionDataFloatFindMap : new LLDictionary(),
	_actionDataVec2FindMap : new LLDictionary(cc.pointEqualToPoint),//std::map<cocos2d::Vec2, int32_t, compareVec2<cocos2d::Vec2>>
	_actionDataVec3FindMap : new LLDictionary(cc.point3EqualToPoint3),//std::map<cocos2d::Vec3, int32_t, compareVec3<cocos2d::Vec3>>
	//allActionMap_ 不保存对象
};
